# -*- coding: utf-8 -*-

"""Main module."""
import io
import logbook
import os
import sys
import yaml
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")))
for p in sys.path: print(p)
from mongo2oracle.log_helper import setup_logbook
from mongo2oracle.mongo_helper import MongoHelper
from mongo2oracle.oracle_helper import OracleHelper


class MainWorker(object):

    def __init__(self):
        self.logger = logbook.Logger(self.__class__.__name__)

    def work(self, conf_file = "convert.yaml"):
        self.logger.info("Loading yaml config file from {}", conf_file)

        def load_conf():
            with io.open(conf_file, mode="r", encoding="utf-8") as f:
                conf = yaml.load(f.read())
                return conf

        oracle_helper = None
        try:
            conf = load_conf()

            mongo_helper = MongoHelper(conf["MongoDB"])
            oracle_helper = OracleHelper(conf["Oracle"])
            batch_size = conf["BATCH_SIZE"]
            if batch_size <= 0:
                batch_size = 100
            tasks = conf["MAPPING"]

            for task in tasks:
                self.logger.info("Processing task {}.", task)
                task = task["task"]
                collection = task["from"]
                oracle_table = task["to"]
                key_map = task["key-map"]

                oracle_helper.truncate_table(oracle_table)
                oracle_helper.prepare_sql(oracle_table, key_map.values(), task["macro"])

                batch_data = []
                for i, data in enumerate(mongo_helper.fetch_data(collection, key_map.keys())):
                    batch_data.append(list(data.values()))

                    if i > 0 and i % batch_size == 0:
                        self.logger.debug("Batch data [0] = {}", batch_data[0])
                        oracle_helper.batch_insert(batch_data)
                        # batch_data.clear()
                        del batch_data[:]
                        self.logger.info("Processed {} records.", i)
                if batch_data:
                    oracle_helper.batch_insert(batch_data)
                    # batch_data.clear()
                    del batch_data[:]
                self.logger.info("Converted {} records from MongoDB/{} to Oracle/{}.", (i+1), collection, oracle_table)
        except Exception:
            self.logger.exception("Meet exception with stack,")
            return 1
        finally:
            if oracle_helper is not None:
                oracle_helper.close()
        return 0


def main(conf_file):
    worker = MainWorker()
    return worker.work(conf_file)


if __name__ == '__main__':
    with setup_logbook("log/converting.log").applicationbound():
        args = sys.argv[1:]
        if len(args) == 0:
            conf_file = os.path.abspath(os.path.join(
                os.path.dirname(os.path.abspath(__file__)), "..", "convert.yaml"))
        else:
            conf_file = args[0]

        sys.exit(main(conf_file))
